//
// Created by wyh on 2025-06-22 10:23.
//
#include <sstream>
#include <cstdarg>
#include "utility/string.h"

using namespace std;
using namespace wyh::utility;

std::string String::to_lower(const string &input)
{
    string str = input;
    std::transform(str.begin(),str.end(),str.begin(),::tolower);
    return str;
}

std::string String::to_upper(const string &input)
{
    string str = input;
    std::transform(str.begin(),str.end(),str.begin(),::toupper);
    return str;
}

std::string String::ltrim(const string &input, const std::string &trims)
{
    string str = input;
    size_t pos = str.find_first_not_of(trims);
    if (pos != string::npos)
    {
        str.erase(0, pos);
    }
    else
    {
        str.clear();
    }
    return str;
}

std::string String::rtrim(const string &input, const std::string &trims)
{
    string str = input;
    size_t pos = str.find_last_not_of(trims);
    if (pos != string::npos)
    {
        str.erase(pos + 1);
    }
    else
    {
        str.clear();
    }

    return str;
}

std::string String::trim(const string &input, const std::string &trims)
{
    string str = ltrim(input,trims);

    return rtrim(str,trims);
}

std::vector<std::string> String::split(const string &input, const string &separator)
{
    vector<string> output;
    size_t last = 0;
    size_t index = input.find_first_of(separator, last);
    while (index != string::npos)
    {
        string str = input.substr(last, index - last);
        output.push_back(str);
        last = index + 1;
        index = input.find_first_of(separator, last);
    }

    if (index - last > 0)
    {
        output.push_back(input.substr(last, index - last));
    }

    return output;
}

std::vector<std::string> String::split(const string &input, char separator)
{
    return split(input,string(1,separator));
}

std::string String::join(const vector<std::string> &input, const string &separator)
{
    ostringstream oss;
    for (auto it = input.begin(); it != input.end(); ++it)
    {
        if (it != input.begin())
        {
            oss<<separator;
        }
        oss << *it;
    }
    return oss.str();
}

std::string String::join(const vector<std::string> &input, char separator)
{
    return join(input,string(1,separator));
}

bool String::has_prefix(const string &input, const string &prefix)
{
    if (input.size() < prefix.size())
    {
        return false;
    }
    return input.substr(0,prefix.size())==prefix;
}

bool String::has_suffix(const string &input, const string &suffix)
{
    if (input.size() < suffix.size())
    {
        return false;
    }
    return input.substr(input.size()-suffix.size(),suffix.size())==suffix;
}

std::string String::capitalize(const string &input)
{
    string str = input;
    if (str.empty())
    {
        return str;
    }

    char ch = input[0];
    if (islower(ch))
    {
        ch = (char) toupper(ch);
        replace(str.begin(), str.begin() + 1, str[0], ch);
    }

    return str;
}

std::string String::format(const char *format, ...)
{
    string result;
    va_list arg_ptr;

    va_start(arg_ptr, format);
    int len = vsnprintf(nullptr, 0, format, arg_ptr);
    va_end(arg_ptr);

    if (len > 0)
    {
        char *buf = new char[len + 1];
        va_start(arg_ptr,format);
        vsnprintf(buf, len + 1, format, arg_ptr);
        va_end(arg_ptr);
        buf[len]=0;
        result = buf;
        delete[] buf;
    }

    return result;
}
